<script lang="ts">
import BFGridApp from './querylist'
import { schema, createDomain } from './biz'
import {
  BFGridSchemaProvider,
  BFGridFormProvider,
  BFGridDomainProvider,
} from './domain-base'
import {
  ArrayField,
  Form,
  ObjectField,
  onFieldInputValueChange,
  onFieldMount,
  onFieldValueChange,
  onFormInit,
  onFormMount,
  createForm,
} from '@formily/core'
import { FormProvider, createSchemaField } from '@formily/vue'
import { Form as FormComponent } from '@formily/vxe-table/src'
import { applyPatch, observe } from './json-patch'
import _ from 'lodash'
import { StoreGeneric } from 'pinia'
import { defineComponent, watch, h, toRef, shallowRef, toRaw } from 'vue'
import {
  GridTablePath,
  useTableField,
  GridPagerPath,
  usePagerField,
  GridSortPath,
  useSortField,
  GridSelectionPath,
  useSelectionField,
  GridFormPath,
  useFormField,
} from './grid-app'
import {
  observable,
  autorun,
  batch,
  model,
  isObservable,
} from '@formily/reactive'
import { useRoute } from 'vue-router'

import * as Components from '@formily/vxe-table/src'
import * as Component from './index'
import { EditComponent } from './edit'

const { SchemaField } = createSchemaField({
  components: {
    ...Components,
    ...Component,
  },
  scope: {
    // global scope 全局的 scope
    BFPermission: (...args) => {
      console.log('validate permission', args)
      return false
    },
  },
})

function useFormilyPiniaBridge(model: StoreGeneric) {
  const formRef = shallowRef<Form>()
  const route = useRoute()

  watch([model.listValue, () => model.listValue], () => {
    const form = formRef.value
    useTableField(form)?.setValue(toRaw(model.listValue))
  })
  watch([model.pagerValue, () => model.pagerValue], () => {
    const form = formRef.value
    usePagerField(form)?.setValue(toRaw(model.pagerValue))
  })
  watch([model.conditionValue, () => model.conditionValue], () => {
    const form = formRef.value
    useFormField(form)?.setValue(toRaw(model.conditionValue))
  })
  watch([model.sortsValue, () => model.sortsValue], () => {
    const form = formRef.value
    useSortField(form)?.setValue(toRaw(model.sortsValue))
  })
  watch([model.selectionsValue, () => model.selectionsValue], () => {
    const form = formRef.value
    useSelectionField(form)?.setValue(toRaw(model.selectionsValue))
  })
  watch(
    () => model.schemaValue,
    () => {
      const form = createForm({
        initialValues: formRef.value
          ? formRef.value.values
          : {
              gridapp: {
                table: model.list,
                pager: model.pager,
                selections: model.selections,
              },
            },
        effects() {
          onFieldMount(GridPagerPath, async (field: ObjectField, form) => {
            model.reload()
          })
          onFieldInputValueChange(GridPagerPath, async (field, form) => {
            const fieldValue = field.value
            model.loadPage({ ...fieldValue, params: route.query })
          })
          onFieldValueChange(GridSelectionPath, async (field, form) => {
            console.log('selections change', field.value)
            model.setSelections(field.value)
          })
          onFieldValueChange(GridSortPath, async (field, form) => {
            console.log('sorts change', field.value)
            model.setSorts(field.value)
          })
          onFieldValueChange('gridapp.form.*', async (field, form) => {
            const formField = form.query(GridFormPath).take() as ObjectField
            console.log('form change', formField.value)
            model.setCondition(formField.value)
          })
        },
      })
      formRef.value = form
    },
    { immediate: true }
  )
  return formRef
}

export default defineComponent({
  name: 'BFGirdApp',
  setup() {
    const domainModel = createDomain() // vuex
    const formRef = useFormilyPiniaBridge(domainModel) // vuex数据同步form数据
    const $route = useRoute()

    const services = [
      {
        name: 'actions',
        type: 'mutation',
        resolver: (params, model, action) => {
          model?.[action.name]()
        },
      },
    ]

    const routes = [
      {
        path: '/',
        view: 'list',
      },
      {
        path: '/create',
        view: 'create',
      },
    ]

    const views = [
      { name: 'list', component: () => {} },
      {
        name: 'create',
        title: 'Back Margin Contract',
        openWay: 'dialog',
        render: () => EditComponent,
        component: EditComponent,
      },
      {
        name: 'detail',
        title: 'Back Margin Contract',
        openWay: 'dialog',
        props: {
          style: {
            width: '100%',
          },
        },
        component: EditComponent,
      },
    ]

    return () => {
      return h(BFGridDomainProvider, { value: domainModel }, [
        h(FormComponent, { form: formRef.value, key: formRef.value.id }, [
          h(
            BFGridApp,
            {
              services: services,
              views: views,
              routes: routes,
            },
            [
              h(SchemaField, {
                schema: domainModel.schemaValue,
                scope: {
                  $route,
                  model: domainModel,
                },
              }),
            ]
          ),
        ]),
      ])
    }
  },
})
</script>

<style lang="scss">
@import './index.scss';
</style>
